#include "tablasimbolos.h"
/* Se inicializa la tabla de simbolos*/
struct registro *ST = NULL;

/*      Se incerta un simbolo dentro de la tabla de simbolos como un nuevo nodo reservando memoria y cada nodo se va 
        incertando al inicio de la tabla de simbolos
*/
struct registro *put_symbol(char *name){
        struct registro *ptr;
        ptr = (struct registro *)malloc(sizeof(struct registro));
        ptr->id = (char *)malloc(sizeof(name)+1);
        strcpy(ptr->id,name);
		ptr->sgte = (struct registro *)ST;
		ptr->prev = NULL;
        //ptr->sgte = NULL;
        //ptr->prev = (struct registro *)ST; 
        ptr->atributos = (struct atributos_simbolos *)malloc(sizeof(struct atributos_simbolos));
        ptr->atributos->alcance = ptr->atributos->tipo = 0;
        /*if(ST != NULL)
                ST->prev = ptr;
        ST = ptr;
	*/
	
		if(ST != NULL)
			ST->prev = ptr;
		ST = ptr;
        return ptr;
}

/* Se obtiene un simbolo de la tabla de simbolos pasandole el nombre del simbolo que se quiere buscar */
struct registro *get_symbol(char *name)
{
        struct registro *ptr;
        for(ptr = ST; ptr!=(struct registro *)0; ptr = ptr->sgte){
                if(strcmp(ptr->id,name) == 0)
                        return ptr;
        }
        return 0;
}
/* Se imprime la tabla de simbolos imprimiendo el contexto y el alcance y el tipo de cada simbolos */ 
void print_ST(struct registro *TS)
{
        struct registro *ptr;
		char *tipo;
        printf("\n*******************************************************************\n");    
        for(ptr=TS; ptr!=NULL; ptr = ptr->sgte){
			
				if(ptr->atributos->tipo == -1)
					tipo = "N/A";
			
			
				else if(ptr->atributos->tipo == 1)
					tipo = "int";
			
				else if(ptr->atributos->tipo == 2)
					tipo = "string";	
			
				else if(ptr->atributos->tipo == 3)
				   tipo = "nil";
			
				else if(ptr->atributos->tipo == 4)
					tipo = "registro";
			
				else if(ptr->atributos->tipo == 5)
					tipo = "array";
				   
                printf("%s : ",ptr->id);
				//printf("alcance: %d, tipo: %s\n", ptr->atributos->alcance, tipo);
				printf("tipo: %s, alcance:%d\n", tipo, ptr->atributos->alcance);

                
        }
        printf("\n");
}
/* Esta fucnion agrega el contexto a cada simbolo  */ 
struct registro *add_context(struct registro *rcd, int value)
{
        rcd->atributos->alcance = value;     
        return rcd;
}

/* Esta funcion agrega el tipo a cada simbolo dentro de la tabla */
struct registro *add_tipo(struct registro *rcd,int value)
{
	rcd->atributos->tipo = value;
    return rcd;
}

/* Esta funcion obtiene el tipo de cada simbolo en la tabla de simbolos */
int get_tipo(struct registro *rcd)
{
	return rcd->atributos->tipo;
}


int get_context(struct registro *rcd)
{
	return rcd->atributos->alcance;
}



/* Esta funcion elimina un simbolo de la tabla de simbolos */
void del_symbol(struct registro *rcd)
{
	struct registro *ptrcd;
    ptrcd = rcd;
    if(ptrcd != NULL)
    {
    	if(rcd->sgte == NULL && rcd->prev == NULL)
    	{
    		rcd = NULL;
            free(ptrcd);                    
        }
        else
        {	
        	if(rcd->prev == NULL)
        	{
        		ST = ptrcd->sgte;
                ptrcd->sgte->prev = NULL;
                ptrcd->sgte = NULL;
                free(ptrcd);
            }
            else
            {
            	if(rcd->sgte == NULL)
            	{	
            		ptrcd->prev->sgte = NULL;
                    ptrcd->prev = NULL;
                    free(ptrcd);
                }
                else
                {
                	ptrcd->prev->sgte = ptrcd->sgte;
                    ptrcd->sgte->prev = ptrcd->prev;
                    ptrcd->prev = NULL;
                    ptrcd->sgte = NULL;
                    free(ptrcd);                                    
                }
            }
                        
        }
                
    }               
}
